#include "error.h"
#include "sockfunc.h"
#include <assert.h>
#include <string.h>
#include <unistd.h>

void
test_readwrite() {
    error_msg("--- test_readwrite");
    int fd[2];
    if (pipe(fd))
        error_dump("fail to create pipe");

    int rfd = fd[0], wfd = fd[1];
    const char *str = "hello from writen";
    int len = strlen(str);
    assert(writen(wfd, str, len) == len);
    error_msg("writen data:%s", str);

    char buf[4096];
    assert(readn(rfd, buf, len) == len);
    buf[len] = 0;
    error_msg("readn data:%s", buf);

    error_msg("--- --- ---");
    str = "hello first line\nhello another line\nhello last line\n";
    len = strlen(str);
    assert(writen(wfd, str, len) == len);
    error_msg("writen data:%s", str);

    assert(readline_slow(rfd, buf, sizeof(buf)) > 0);
    error_msg("read first line:%s", buf);
    assert(readline_slow(rfd, buf, sizeof(buf)) > 0);
    error_msg("read second line:%s", buf);
    assert(readline_buffer(rfd, buf, sizeof(buf)) > 0);
    error_msg("read last line:%s", buf);

    str = "test line1\ntest line2\n";
    len = strlen(str);
    assert(writen(wfd, str, len) == len);
    error_msg("writen data:%s", str);

    assert(readline_buffer(rfd, buf, sizeof(buf)) == strlen("test line1"));
    error_msg("read line1:%s", buf);
    assert(readline_buffer(rfd, buf, sizeof(buf)) == strlen("test line2"));
    error_msg("read line2:%s", buf);

    close(rfd);
    close(wfd);
}

void
test_sockname() {
    error_msg("--- test_sockname");
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    assert(sockfd_to_family(fd) == AF_INET);
    fd = socket(AF_INET6, SOCK_STREAM, 0);
    assert(sockfd_to_family(fd) == AF_INET6);
}

void
test_host_serv() {
    error_msg("--- test_host_serv try for tcp");
    struct addrinfo *res, *ptr;
    ptr = res = host_serv(NULL, "1000", AF_UNSPEC, SOCK_STREAM);
    assert(res != NULL);
    while (res) {
        error_msg("canonname:%s addr:%s", res->ai_canonname, sock_ntop(res->ai_addr, res->ai_addrlen));
        res = res->ai_next;
    }
    freeaddrinfo(ptr);

    error_msg("--- test_host_serv try for udp");
    ptr = res = host_serv(NULL, "1000", AF_UNSPEC, SOCK_DGRAM);
    assert(res != NULL);
    while (res) {
        error_msg("canonname:%s addr:%s", res->ai_canonname, sock_ntop(res->ai_addr, res->ai_addrlen));
        res = res->ai_next;
    }
    freeaddrinfo(ptr);
}

int
main() {
    test_readwrite();
    error_msg(" ");
    test_sockname();
    error_msg(" ");
    test_host_serv();
    error_msg("all test pass");
    return 0;
}

